package tt.dz.tcp.socket;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import redis.clients.jedis.Jedis;
import tt.dz.entity.exception.BizException;
import tt.dz.service.imp.middleware.instruction.Ev3c2Instructions;
import tt.dz.service.imp.middleware.instruction.Ev3cInstructions;
import tt.dz.service.imp.middleware.instruction.Instruction;
import tt.dz.service.imp.middleware.instruction.InstructionType;
import tt.dz.service.imp.middleware.vo.UnSendingMessage;
import tt.dz.service.middleware.MessageService;
import tt.dz.util.RedisClient;
import tt.dz.util.StringUtil;

import javax.annotation.Resource;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 消息接收事件监听器实现类
 */
@Component
public class ReceiveEventListenerImpl implements ReceiveEventListener
{
	private Log log = LogFactory.getLog(ReceiveEventListenerImpl.class);

	@Resource(name = "ev3cMessageServiceImpl")
	MessageService ev3cMessageService;
	@Resource(name = "ev3c2MessageServiceImpl")
	MessageService ev3c2MessageService;

	@Override
	public void onReceiveMessage(String message, Channel channel)
	{
		try
		{
			//Map<String, String> map = StringUtil.ev3cString2JSONObject(message);
			Map<String, String> map = null;

			JSONObject json = (JSONObject) JSON.parse(message);
			String chargerId = json.getString("chargerId");
			String protocol_type = json.getString("protocol_type");
			String protocol_version = json.getString("protocol_version");

			if (StringUtils.isEmpty(chargerId))
				throw new BizException("chargerId is null");

			if ("99".equals(protocol_type))
			{//charger offline
				ev3cMessageService.offlineCharger(chargerId);
			}
			else if ("1".equals(protocol_type))
			{
				MessageService msgsvc = null;
				String command = null;
				Instruction instruction = null;
				if ("0101".equals(protocol_version) || "0102".equals(protocol_version))
				{
					map = StringUtil.ev3cString2JSONObject(message);
					command = map.get("frameType");
					instruction = Ev3cInstructions.parse(command);
					msgsvc = ev3cMessageService;
				}
				else if ("0201".equals(protocol_version))
				{
					map = StringUtil.ev3c2String2JSONObject(message);
					command = map.get("data").substring(6, 8);
					instruction = Ev3c2Instructions.parse(command);
					msgsvc = ev3c2MessageService;
				}
				else
					throw new BizException("invalid protocol version");

				//如果是桩回复的报文, 需要找到匹配的服务器下发报文并标记出来
				if (instruction.type() == InstructionType.ReplyByCharger)
				{
					Jedis jedis = null;
					try
					{
						jedis = RedisClient.getConnect();
						String sending_key = "unsendmsg_" + chargerId;
						String serial_no = null;

						if ("0201".equals(protocol_version))
							serial_no = map.get("data").substring(38, 56);

						List<String> list_msg = jedis.lrange(sending_key, 0, -1);
						int index = 0;
						boolean foundRelatedSendingMsg = false;
						String relatedMsg = null;
						for (; index < list_msg.size(); index++)
						{
							String msgstring = list_msg.get(index);
							UnSendingMessage msg = JSON.parseObject(msgstring, UnSendingMessage.class);
							if ("0201".equals(protocol_version))
							{
								if (serial_no != null && serial_no.equals(msg.getMessage().substring(32, 50)))
								{
									foundRelatedSendingMsg = true;
									relatedMsg = msg.getMessage();
									break;
								}
							}
							else
							{
								if (((Ev3cInstructions) instruction).replyFor() == Ev3cInstructions.parse(msg.getCommand()))
								{
									foundRelatedSendingMsg = true;
									relatedMsg = msg.getMessage();
									break;
								}
							}
						}

						if (foundRelatedSendingMsg)
						{
							map.put("replyFor", relatedMsg);
							list_msg.remove(index);
							jedis.del(sending_key);
							if (list_msg != null && list_msg.size() > 0)
								jedis.rpush(sending_key, list_msg.toArray(new String[list_msg.size()]));
						}

					}
					catch (Exception e)
					{
						log.error(e.getMessage(), e);
					}
					finally
					{
						if (jedis != null)
							jedis.close();
					}
				}

				msgsvc.receive(map, channel);
				map = null;//pengyu add 20161220
			}

		}
		catch (Exception ex)
		{
			log.error(ex.getMessage(), ex);
		}

	}
}
